home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 December / PCWDEC07.iso / Software / Freeware / FlashGot 0.6.4 / chrome / flashgot.jar / content / flashgot / flashgotOverlay.js < prev    next >
Encoding:
JavaScript  |  2007-08-29  |  28.2 KB  |  900 lines

  1. /***** BEGIN LICENSE BLOCK *****
  2.     FlashGot - a Firefox extension for external download managers integration
  3.     Copyright (C) 2004-2006 Giorgio Maone - g.maone@informaction.com
  4. ***** END LICENSE BLOCK *****/
  5.  
  6. function FlashGotOverlay() {
  7.   
  8.   try {
  9.     gFlashGot = this;
  10.     
  11.     if(!gFlashGotService) throw new Error("FlashGotService not registered!");
  12.     
  13.     // install listeners
  14.  
  15.     window.addEventListener("mouseover", function(ev) {
  16.       gFlashGot.hoverElement = ev.target;
  17.     }, false);
  18.     
  19.     window.addEventListener("mouseup", function(ev) {
  20.       gFlashGotService.interceptor.bypassAutoStart = false;
  21.       gFlashGotService.interceptor.forceAutoStart = false;
  22.       if(ev.altKey && !(ev.ctrlKey || ev.metaKey)) {
  23.         function prevent() {
  24.           ev.preventDefault();
  25.           ev.stopPropagation();
  26.           gFlashGot.lastClickCaptureTime=new Date().getTime();
  27.         }
  28.         if(ev.shiftKey) {
  29.           gFlashGotService.interceptor.bypassAutoStart =
  30.             gFlashGotService.getPref("bypassCombo",true);
  31.         } else {
  32.           if(gFlashGotService.getPref("altClick")) {
  33.             try {
  34.               if(gFlashGot.downloadSel() || gFlashGot.downloadLink()) {
  35.                 prevent();
  36.                 return;
  37.               }
  38.             } catch(ex) {}
  39.             gFlashGotService.interceptor.forceAutoStart = true;
  40.           } else {
  41.             return;
  42.           } 
  43.         }
  44.         ev2 = ev.view.document.createEvent("MouseEvents");
  45.         ev2.initMouseEvent("click",ev.canBubble, ev.cancelable, 
  46.                            ev.view, ev.detail, ev.screenX, ev.screenY, 
  47.                            ev.clientX, ev.clientY, 
  48.                            //ev.ctrlKey, ev.altKey, ev.shiftKey, ev.metaKey,
  49.                            false,false,false,false,
  50.                            ev.button, ev.relatedTarget);
  51.         prevent();
  52.         gFlashGot.hoverElement.dispatchEvent(ev2);
  53.       }
  54.     }, true);
  55.     
  56.     window.addEventListener("click",function(ev) {
  57.       if(ev.altKey && 
  58.         typeof(gFlashGot.lastClickCaptureTime) == "number" && 
  59.         new Date().getTime()-gFlashGot.lastClickCaptureTime < 100
  60.       ) {
  61.         ev.preventDefault();
  62.         ev.stopPropagation();
  63.       }
  64.     }, true);
  65.     
  66.     
  67.     this.contextMenu.addEventListener("popupshowing",function(ev) {
  68.         if(this == ev.explicitOriginalTarget) {
  69.           gFlashGot.prepareContextMenu(ev);
  70.         }
  71.       },false);
  72.     
  73.     this.toggleMainMenuIcon();
  74.     
  75.     const prevVer = gFlashGotService.getPref("version", "");
  76.     if(prevVer != gFlashGotService.VERSION) {
  77.       gFlashGotService.setPref("version", gFlashGotService.VERSION);
  78.       if(gFlashGotService.getPref("firstRunRedirection", true)) {
  79.         window.setTimeout(function() {
  80.           const url = "http://flashgot.net?ver=" + gFlashGotService.VERSION + "&prev=" + prevVer;
  81.           const browser = getBrowser();
  82.           browser.selectedTab = browser.addTab(url, null);
  83.         }, 100);
  84.       }
  85.     }
  86.     
  87.     if(typeof(flashgot_doDirtyJobs) == "function") {
  88.       window.setTimeout(flashgot_doDirtyJobs,0);
  89.     }
  90.     
  91.     
  92.   } catch(err) {
  93.     dump("FlashGot init error: " + err.message);
  94.     this.log("Unrecoverable init error: " + err.message);
  95.   }
  96.   
  97.   
  98.   
  99. }
  100.  
  101.  
  102. FlashGotOverlay.prototype = {
  103.   hoverElement: null
  104.   log: function(msg) {
  105.     gFlashGotService.log(msg);
  106.   }
  107. ,
  108.   _contextMenu: null,
  109.   get contextMenu() {
  110.     var cm=this._contextMenu;
  111.     if(!cm) {
  112.       this._contextMenu = cm = 
  113.         document.getElementById("contentAreaContextMenu") || 
  114.         document.getElementById("messagePaneContext")
  115.     }
  116.     return cm;
  117.   }
  118. ,
  119.   switchOption: function(opt) {
  120.     gFlashGotService.setPref(opt, !gFlashGotService.getPref(opt));
  121.   }
  122. ,
  123.   openOptionsDialog: function() {
  124.     window.open("chrome://flashgot/content/flashgotOptions.xul", "flashgotOptions",
  125.       "chrome,dialog,centerscreen,alwaysRaised");
  126.   }
  127. ,
  128.   openAboutDialog: function() {
  129.     window.open("chrome://flashgot/content/about.xul", "flashgotAbout",
  130.       "chrome,dialog,centerscreen");
  131.   }
  132. ,
  133.   browse: function(url) {
  134.     var browser =  window.getBrowser();
  135.     browser.selectedTab = browser.addTab(url, null);
  136.   }
  137. ,
  138.   browseHomePage: function() {
  139.     this.browse("http://flashgot.net");
  140.   }
  141. ,
  142.   get hideIcons() {
  143.     return gFlashGotService.getPref("hide-icons", false);
  144.   }
  145. ,
  146.   toggleIcon: function(m, hide) {
  147.     if(!m) return;
  148.     const iconicClass=m.tagName+"-iconic";
  149.     const rx=new RegExp("\\b"+iconicClass+"\\b");
  150.     if(hide) {
  151.       m.className=m.className.replace(rx,"").replace(/\bflashgot-icon-(\w+)\b/,'flashgot-noicon-$1');
  152.     } else {
  153.       const cl=m.className;
  154.       if(!rx.test(cl)) {
  155.         m.className=cl.replace(/\bflashgot-noicon-(\w+)\b/,'flashgot-icon-$1')+" "+iconicClass;
  156.       }
  157.     }
  158.   }
  159. ,
  160.   toggleMainMenuIcon: function() {
  161.     this.toggleIcon(document.getElementById("flashgot-menu"),this.hideIcons);
  162.   }
  163. ,
  164.   prepareToolsMenu: function(ev) {
  165.     
  166.     function toggleMenu(id,disabled) {
  167.       id="flashgot-main-menuitem-"+id;
  168.       var m=document.getElementById(id);
  169.       if(!m) return;
  170.       m.setAttribute("disabled",disabled);
  171.       gFlashGot.toggleIcon(m,hideIcons);
  172.     }
  173.     
  174.     if(gFlashGotService && !(document.getElementById("flashgot-menu").hidden = gFlashGotService.getPref("hide-menu"))) {
  175.       const dis = !gFlashGotService.DMS.found;
  176.       const hideIcons = this.hideIcons;
  177.       toggleMenu("tabs", dis || !this.isTabbed); 
  178.       toggleMenu("all",dis);
  179.       toggleMenu("sel", dis || this.isSelInvalid);
  180.       toggleMenu("buildGallery",false);
  181.       toggleMenu("opts",false);
  182.       this.prepareOptsMenu(ev.target);
  183.     }
  184.   }
  185. ,
  186.   
  187.   prepareContextMenu: function(ev) {
  188.     
  189.     this.toggleMainMenuIcon();
  190.     var menuCount = 0;
  191.     
  192.     function menuSwitch(name, disabled) {
  193.       var menuItem = document.getElementById("flashgot-menuitem-" + name);
  194.       
  195.       if(menuItem && 
  196.         ! ( menuItem.hidden = 
  197.             ( hidden || gFlashGotService.getPref("hide-" + name) ) )
  198.       ) {
  199.        menuItem.setAttribute("disabled", disabled ? "true" : "false");
  200.        if(! (menuItem.hidden=disabled && hideDisabled) ) {
  201.          menuCount++;
  202.        }
  203.        gFlashGot.toggleIcon(menuItem, hideIcons);
  204.       }
  205.     }
  206.     const defaultDM = gFlashGotService.defaultDM;  
  207.     const dms = gFlashGotService.DMS;
  208.     var dm = dms.found ? dms[defaultDM] : null;
  209.     
  210.     var iGetterMenu = document.getElementById("all-igetter");
  211.     if(iGetterMenu) try {
  212.        // if(dm && (defaultDM == "iGetter Win") {
  213.         iGetterMenu.style.display = "none";  
  214.         document.getElementById("igetter-link").style.display = "none";
  215.        // } else {
  216.        // iGetterMenu.style.display = "";  
  217.        // document.getElementById("igetter-link").style.display = "";
  218.       // }
  219.     } catch(e) {}
  220.  
  221.     const invalidLink = !this.popupLink;
  222.    
  223.     const invalidSel = this.isSelInvalid;
  224.     
  225.     const noLink = this.linksCount == 0;
  226.     const hideDisabled = gFlashGotService.getPref("hideDisabledCmds");
  227.    
  228.     
  229.     var hidden = !(dms.found && dm);
  230.     const hideIcons = this.hideIcons;
  231.     
  232.     var hideLink = invalidLink || hidden || dm.disabledLink;
  233.     var hideSel = invalidSel || hidden  || dm.disabledSel;
  234.     this.prepareCommandsMenu(document.getElementById("flashgot-menuitem-it"), hideLink && hideSel);
  235.     
  236.     menuSwitch("it",  hideLink);
  237.     menuSwitch("sel", hideSel);
  238.     menuSwitch("all", noLink || hidden || dm.disabledAll);
  239.     menuSwitch("tabs", (! (typeof(gBrowser)=="object" 
  240.       && gBrowser.browsers && gBrowser.browsers.length>1) ) 
  241.                            || hidden || dm.disabledAll);
  242.     menuSwitch("autotest", hidden);
  243.     hidden=false;
  244.     menuSwitch("buildGallery", false);
  245.     
  246.     const optsMenu = document.getElementById("flashgot-menu-options");
  247.     this.toggleIcon(optsMenu,hideIcons);
  248.     if(!(optsMenu.hidden = gFlashGotService.getPref("hide-options"))) {
  249.       menuCount++;
  250.     }
  251.     
  252.     const submenu = document.getElementById("flashgot-submenu");
  253.     this.toggleIcon(submenu, hideIcons);
  254.     const subanchor = document.getElementById("flashgot-submenu-anchor");
  255.     const subpop = subanchor.parentNode;
  256.     const sep1 = document.getElementById("flashgot-context-separator");
  257.     const sep2 = document.getElementById("flashgot-context-separator2");
  258.     const menu = sep1.parentNode;
  259.     var next=null;
  260.     
  261.     const nested = gFlashGotService.getPref("nested-menu") && (menuCount>1);
  262.     submenu.hidden = !nested;
  263.     if(nested) {
  264.       menuCount=0;
  265.       if(!subanchor.nextSibling) {
  266.         document.getElementById("flashgot-menuitem-tabs").setAttribute("accesskey", document.getElementById("flashgot-main-menuitem-tabs").getAttribute("acceskey"));
  267.         for(menuItem = sep1.nextSibling;
  268.             menuItem && (menuItem != sep2); 
  269.             menuItem = next) {
  270.           next=menuItem.nextSibling;
  271.           subpop.appendChild(menuItem);
  272.         }
  273.       }
  274.     } else {
  275.       document.getElementById("flashgot-menuitem-tabs").removeAttribute("accesskey");
  276.       for(var menuItem = subanchor.nextSibling; menuItem; menuItem = next) {
  277.         next=menuItem.nextSibling;
  278.         menu.insertBefore(menuItem,sep2);
  279.       }
  280.     }
  281.     sep1.hidden = menuCount == 0;
  282.   }
  283. ,
  284.   prepareCommandsMenu: function(anchorNode, hideOnly) {
  285.     var node, parentNode = anchorNode.parentNode;
  286.     while((node = anchorNode.previousSibling) && /\bflashgot-command-menuitem\b/.test(node.className)) {
  287.       parentNode.removeChild(node);
  288.     }
  289.     if(hideOnly) return;
  290.     
  291.     var mi, dm;
  292.     const dms = gFlashGotService.DMS;
  293.     for(var j = 0, len = dms.length; j < len; j++) {
  294.       dm = dms[j];
  295.       if(dm.supported && dm.shownInContextMenu) {
  296.         mi = document.createElement("menuitem");
  297.         mi.setAttribute("class", "menuitem-iconic flashgot-command-menuitem");
  298.         mi.setAttribute("label", dm.name);
  299.         mi.setAttribute("id", "flashgot-command-mi-" + dm.codeName);
  300.         mi.setAttribute("oncommand", "gFlashGot.downloadPopupLink(this.label) || gFlashGot.downloadSel(this.label)");
  301.         parentNode.insertBefore(mi, anchorNode);
  302.       }
  303.     }
  304.   },
  305.   
  306.   prepareOptsMenu: function(parentNode) {
  307.    
  308.     const opts = parentNode.getElementsByTagName("menuitem");
  309.     
  310.     this.toggleIcon(document.getElementById("flashgot-tbb-menuitem-opts"), this.hideIcons);
  311.     
  312.     var menuItem, id, match, lastMenu=null, isTBB=false;
  313.     var j = opts.length;
  314.     while(j-- > 0) {
  315.       menuItem = opts[j];
  316.       if((id=menuItem.id)) {
  317.         if((match = id.match(/opt-(.*)/))) {
  318.           menuItem.setAttribute("checked",
  319.             gFlashGotService.getPref(match[1]) ? "true" : "false");
  320.         } else if((match = id.match(/^flashgot-(\w+)-menuitem-nodms$/))) {
  321.           lastMenu = menuItem;
  322.           isTBB = match[1]=="tbb";
  323.         }
  324.       }
  325.     }
  326.     
  327.     if(!lastMenu) return;
  328.     
  329.     const defaultDM = gFlashGotService.defaultDM;  
  330.     const dms = gFlashGotService.DMS;
  331.     var menuItemId;
  332.     if(dms.found) {
  333.       var idPrefix="flashgot-menuopt-dm-";
  334.       var eventPostfix;
  335.       if(isTBB) {
  336.         idPrefix += "tbb-";
  337.         eventPostfix = "gFlashGot.downloadSel() || gFlashGot.downloadAll()";
  338.         var rsMenu = document.getElementById("flashgot-tbb-menuitem-rsPremium");
  339.         if(gFlashGotService.getPref("rsPremium", false)) {
  340.           rsMenu.removeAttribute("hidden");
  341.         } else {
  342.           rsMenu.setAttribute("hidden", "true");
  343.         }
  344.       } else {
  345.         eventPostfix = "gFlashGot.downloadPopupLink() || gFlashGot.downloadSel()";
  346.       }
  347.       lastMenu.setAttribute("hidden", "true");
  348.       parentNode = lastMenu.parentNode;
  349.       var dm;
  350.       const miclass = "flashgot-dms-entry";
  351.       // add menu items
  352.       for(j = dms.length; j-- >0;) {
  353.         dm = dms[j];
  354.         if(dm.supported) {
  355.           menuItemId = idPrefix + dm.codeName;
  356.           menuItem = document.getElementById(menuItemId);
  357.           if(!menuItem) {
  358.             menuItem = document.createElement("menuitem");
  359.             menuItem.setAttribute("class", miclass);
  360.             menuItem.setAttribute("id", menuItemId);
  361.             menuItem.setAttribute("type", "radio");
  362.             menuItem.setAttribute("autocheck", "true");
  363.             menuItem.setAttribute("oncommand", 
  364.                 "gFlashGotService.defaultDM = this.label; window.setTimeout(function() { " + 
  365.                   eventPostfix + " }, 0)");
  366.             menuItem.setAttribute("label", dm.name);
  367.             parentNode.insertBefore(menuItem, lastMenu);
  368.           }
  369.           menuItem.setAttribute("checked", (defaultDM == dm.name) ? "true" : "false");
  370.           lastMenu = menuItem;
  371.         }
  372.       }
  373.       // remove menu items
  374.       var nodes=parentNode.getElementsByAttribute("class", miclass);
  375.       for(j=nodes.length; j-->0;) {
  376.         dm=dms[nodes[j].getAttribute("label")];
  377.         if(!(dm && dm.supported)) {
  378.           parentNode.removeChild(nodes[j],true);
  379.         }
  380.       }
  381.     } else {
  382.       lastMenu.removeAttribute("hidden");
  383.     }
  384.   }
  385. ,
  386.   get unwrappedWindow() {
  387.     return window.content;
  388.   }
  389. ,
  390.   get srcWindow() {
  391.     return new XPCNativeWrapper(document.commandDispatcher.focusedWindow, 
  392.       "document", "getSelection()");
  393.   }
  394. ,
  395.   get srcDocument() {
  396.     return this.wrapDocument(this.srcWindow.document);
  397.   }
  398. ,
  399.   wrapDocument: function(doc) {
  400.     return new XPCNativeWrapper(doc, "getElementsByTagName()", "links", "embeds",
  401.      "images", "URL", "referrer", "cookie");
  402.   }
  403. ,
  404.   get isTabbed() {
  405.     var b=getBrowser();
  406.     return b && b.browsers && b.browsers.length>1;
  407.   }
  408. ,
  409.   get isSelInvalid() {
  410.     return this.srcWindow.getSelection().isCollapsed;
  411.   }
  412. ,
  413.   get popupLink() { 
  414.     return this.findLinkAsc(document.popupNode);
  415.   }
  416. ,
  417.   get linksCount() {
  418.     function len(node) {
  419.       return gFlashGotService.lookupMethod(node,"length")();
  420.     }
  421.     const doc=this.srcDocument;
  422.     if(!doc) return 0;
  423.     var count=len(doc.links);
  424.     if(gFlashGotService.getPref("includeImages")) count+=len(doc.images);
  425.     count+=len(doc.embeds);
  426.     return count;
  427.   }
  428. ,
  429.   getLinks: function(filter, includeImages, doc) {
  430.     if(typeof(doc) != "object") {
  431.       doc = this.srcDocument;
  432.     }
  433.     if(doc == null) return [];
  434.     const allLinks = [];
  435.     const lm = gFlashGotService.lookupMethod;
  436.  
  437.  
  438.     function wrapAndFilter(newL, l) {
  439.       const href = lm(l,"src")();
  440.       if(!href) return null;
  441.       
  442.       if(href.lastIndexOf("://",9) < 0) {
  443.         try {
  444.           newL.href = 
  445.                 (uriResolver || 
  446.                  (uriResolver = 
  447.                   Components.classes['@mozilla.org/network/io-service;1']
  448.                             .getService(Components.interfaces.nsIIOService)
  449.                             .newURI(doc.URL,null,null))).resolve(href);
  450.         } catch(ex) {
  451.           return false;
  452.         }
  453.       } else {
  454.         newL.href =  href 
  455.       }
  456.       
  457.       const ga = lm(l, "getAttribute");
  458.       var des = ga("alt") || ga("title") || href.substring(href.lastIndexOf("/") + 1);
  459.       var w, h;
  460.       (w = ga("width")) && (h = ga("height")) && (des += " (" + w + "," + h + ")");
  461.  
  462.       newL.description = des;
  463.  
  464.       return filter(newL, l);
  465.     }
  466.     
  467.     function filterLinks(elems, filter, tagName) {
  468.       const wrap = tagName == "A";
  469.       try {
  470.         if(elems) {
  471.           var l, newL;
  472.           const e_item = lm(elems,"item");
  473.           for(var j = 0, len = lm(elems,"length")(); j < len; j++) {
  474.             l = e_item(j);
  475.             newL = wrap ? gFlashGot._wrapAnchor(l, lm) : { tagName: tagName };
  476.             if(newL && filter(newL, l)) {
  477.               allLinks[allLinks.length] = newL;
  478.             }
  479.           }
  480.         }
  481.       } catch(ex) {}
  482.     }
  483.     
  484.     
  485.     
  486.     filterLinks(doc.links, filter, "A"); 
  487.     
  488.     var uriResolver = null;
  489.     
  490.     if(includeImages) {
  491.       filterLinks(doc.images, wrapAndFilter,"IMG");
  492.     }
  493.     
  494.     filterLinks(doc.embeds,wrapAndFilter,"EMBED");
  495.  
  496.     return allLinks;
  497.   }
  498. ,
  499.   get referrer() {
  500.     if(this._referrer) return this._referrer;
  501.     var docURL = this.srcDocument.URL;
  502.     var gb = docURL && docURL.substring(0,5)=="file:" && this.unwrappedWindow._flashgotGB;
  503.     return gb ? gb.referrer : docURL;
  504.   }
  505. ,  
  506.   set referrer(r) {
  507.     return this._referrer = r; 
  508.   }
  509. ,
  510.   getSelectionLinks: function(includeImages) {
  511.     const selection = this.srcWindow.getSelection();
  512.     
  513.     // link nodes detection
  514.     var links = this.getLinks(function(link, trueNode) {
  515.       return link && gFlashGot.checkLink(link) && 
  516.         selection.containsNode(trueNode ? trueNode : link, true); 
  517.     }, includeImages); 
  518.     
  519.     var selString = selection.toString();
  520.     var m;
  521.     
  522.     // password detection
  523.     var pwd = gFlashGotService.getPref("selection.guessPassword", true) &&
  524.         (m = selString.match(/\s(?:password|passw|pass|pwd|pw)\W+(.*)/i)) && m[1];
  525.  
  526.     // text links detection
  527.     m = selString.match(
  528.       /\b(h.{2}p:\/\/|ftp:\/\/|mms:\/\/|rtsp:\/\/|[a-z]+[a-z\d]+\.[a-z\d\-\.]+\/)[^\s]*/gi);
  529.     delete selString;
  530.     var j, k;
  531.     if(m) {
  532.       var descMap = null;
  533.       var href;
  534.       for(j = 0, len = m.length; j < len; j++) {
  535.         href = m[j].replace(/^h.{2}p/i, "http").replace(/^([a-z]+[a-z\d]+\.[a-z\d\.]+\/)/i, "http://$1");
  536.         if(href) {
  537.           if(!descMap) { // we use it to avoid textual "quasi-duplicates", as http://somepart...oftheurl
  538.             descMap = {};
  539.             for(k = links.length; k-- > 0;) {
  540.               descMap[links[k].description] = true;
  541.             }
  542.           }
  543.           if(descMap[href] || descMap[m[j]]) continue;
  544.           links[links.length] = {href: href, description: m[j]};
  545.         }
  546.       }
  547.     }
  548.     
  549.     if(pwd) {
  550.       var des;
  551.       pwd = " pw: " + pwd;
  552.       for(j = links.length; j-- > 0;) {
  553.         des = links[j].description || "";
  554.         links[j].description = des.substring(0, 4) == "http" ? pwd : des.concat(pwd);
  555.       }
  556.     }
  557.     return links;
  558.   }
  559. ,
  560.   checkLink: function(link) {
  561.     return link.href && /^[a-z]+:\/\/.*/i.test(link.href) && !/^(javascript|mailto|news|file|data):/i.test(link.href);
  562.   }
  563. ,
  564.   _wrapAnchor: function(node,lm) {
  565.     var isAnchor = (node instanceof HTMLAnchorElement);
  566.     if(isAnchor || node instanceof HTMLAreaElement) {
  567.         var href = lm(node, "href")();
  568.         if(href) return { 
  569.           href: href,
  570.           tagName: "A",
  571.           getElementsByTagName: lm(node,"getElementsByTagName"),
  572.           description: isAnchor 
  573.             ? (d = lm(node,"title")()) && d.replace(/\s+/g," ") || 
  574.               (d = lm(node, "innerHTML")()) && d.replace(/\s+/g," ")
  575.                                             .replace(/<.*?>/g, "") 
  576.             : (d = (lm(node, "alt")() || lm(node, "title")())) &&
  577.                d.replace(/\s+/g," ") 
  578.           };
  579.     }
  580.     return null;
  581.   }
  582. ,
  583.   findLinkAsc: function(node) {
  584.      const lm = gFlashGotService.lookupMethod;
  585.      var anchor;
  586.      while(node) {
  587.       anchor=this._wrapAnchor(node,lm);
  588.       if(anchor) return this.checkLink(anchor) ? anchor : null;
  589.       node = lm(node,"parentNode")();
  590.     }
  591.     return null;
  592.   }
  593. ,
  594.   delayCmd: function(cmd) {
  595.     const pg = this.createProgress();
  596.     pg.update(5);
  597.     window.setTimeout(function() {
  598.       try {
  599.         pg.value = 100;
  600.         gFlashGot["download"+cmd]();
  601.       } catch(ex) {
  602.         dump(ex);
  603.       }
  604.     },0);
  605.   }
  606. ,
  607.   downloadPopupLink: function(dmName) {
  608.     const link = this.popupLink;
  609.     if(link != null) {
  610.       this.download([link], gFlashGotService.OP_ONE, dmName);
  611.     }
  612.   }
  613. ,
  614.   downloadLink: function(dmName) {
  615.     const sel=this.srcWindow.getSelection();
  616.     var link=this._wrapAnchor(sel.anchorNode, gFlashGotService.lookupMethod);
  617.     if(!link) {
  618.       link=this.findLinkAsc(this.hoverElement);
  619.     }
  620.     return link ? this.download([link], gFlashGotService.OP_ONE, dmName):false;
  621.   }
  622. ,
  623.   downloadSel: function(dmName) {
  624.     if(this.isSelInvalid) return false;
  625.     const startTime = new Date().getTime();
  626.     const links = this.getSelectionLinks(gFlashGotService.getPref("includeImages"));
  627.     links.startTime = startTime;
  628.     return this.download(links, gFlashGotService.OP_SEL,dmName);
  629.   }
  630. ,
  631.  WrappedCollection: function(coll) {
  632.   this.item = gFlashGotService.lookupMethod(coll, "item");
  633.   this.length = gFlashGotService.lookupMethod(coll, "length")();
  634.  }
  635. ,
  636.   collectAllLinks: function(doc ,tagName) {
  637.     var links=[];
  638.     const includeImages=gFlashGotService.getPref("includeImages");
  639.     if(tagName) {
  640.       var frames=new this.WrappedCollection(doc.getElementsByTagName(tagName));
  641.       const lm = gFlashGotService.lookupMethod;
  642.       var contentDocument;
  643.       for(var j=frames.length; j-->0;) {
  644.         try {
  645.           if((contentDocument = lm(frames.item(j), "contentDocument")())) {
  646.             links=links.concat(
  647.               this.collectAllLinks(contentDocument));
  648.           }
  649.         } catch(ex2) {
  650.         }
  651.       }
  652.     } else {
  653.       links = links.concat(this.getLinks(this.checkLink, includeImages, doc)
  654.         ).concat(this.collectAllLinks(doc,"frame")
  655.         ).concat(this.collectAllLinks(doc,"iframe"));
  656.     }
  657.     return links;
  658.   }
  659. ,
  660.   downloadAll: function(dmName) {
  661.     const startTime = new Date().getTime();
  662.     const links = this.collectAllLinks(
  663.       this.wrapDocument(gFlashGotService.lookupMethod(window.content,"document")())
  664.     );
  665.     links.startTime = startTime;
  666.     return this.download(links, gFlashGotService.OP_ALL, dmName);
  667.   }
  668. ,
  669.   downloadTabs: function(dmName) {
  670.     if(!this.isTabbed) return this.downloadAll(dmName);
  671.     const bb=getBrowser().browsers;
  672.     var doc;
  673.     var links=[];
  674.     for(var j=0,len=bb.length; j<len; j++) {
  675.       if((doc=bb[j].contentDocument)) {
  676.         links=links.concat(this.collectAllLinks(this.wrapDocument(doc)));
  677.       }
  678.     }
  679.     if(links.length) {
  680.       return this.download(links,gFlashGotService.OP_ALL, dmName);
  681.     }
  682.     return false;
  683.   }
  684. ,
  685.   autotest: function() {
  686.    
  687.     const ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"
  688.       ].getService(Components.interfaces.nsIPromptService);
  689.  
  690.  
  691.     var flags=ps.BUTTON_OK * ps.BUTTON_POS_0 +
  692.           ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_1 +
  693.           ps.BUTTON_TITLE_CANCEL  * ps.BUTTON_POS_2;
  694.  
  695.     const dms=gFlashGotService.DMS;
  696.     const ops={
  697.       Link: this.downloadLink, 
  698.       Selection: this.downloadSel,
  699.       All: this.downloadAll 
  700.     };
  701.     var dm,opName,res,opFunc;
  702.     for(var j=dms.length; j-- >0;) {
  703.       dm=dms[j];
  704.       if(dm.supported) {
  705.         for(opName in ops) {
  706.           res=ps.confirmEx(window,"FlashGot Autotest",
  707.                   "Performing FlashGot "+opName+" on "+dm.name,
  708.                   flags, null, "Skip", null, null, {});
  709.           if(res==0) {
  710.             opFunc=ops[opName];
  711.             try {
  712.               opFunc.call(this,dm.name);
  713.             } catch(ex) {
  714.               alert("Error:\n"+ex.message);
  715.               throw ex;
  716.             }
  717.           } else if(res==2) return;
  718.         }
  719.       }
  720.     }
  721.   }
  722. ,
  723.   download: function(links, opType, dmName) {
  724.     try {
  725.       links.referrer=this.referrer;
  726.       links.document=this.srcDocument;
  727.     } catch(ex) {}
  728.     
  729.     links.progress = this.createProgress();
  730.     const ret = gFlashGotService.download(links, opType, dmName);
  731.     
  732.     return ret;
  733.   }
  734. ,
  735.   progressList: [],
  736.   createProgress: function(v) {
  737.     return new this.Progress(v);
  738.   },
  739.   Progress: function(v) {
  740.     this.value = v || 0;
  741.     this.showing = false;
  742.     this.update = function(v) {
  743.       if(!this.showing) {
  744.         this.showing = true;
  745.         gFlashGot.progressList.push(this);
  746.       }
  747.       if(typeof(v) == "number") this.value = v;
  748.       gFlashGot.showProgress();
  749.     }
  750.   },
  751.   
  752.   showProgressValue: function(v) {
  753.     document.getElementById("flashgot-progresspanel").setAttribute("collapsed",
  754.         v < 100 ? "false" : "true");
  755.     document.getElementById("flashgot-progressmeter").value = v;
  756.     gFlashGotService.yield();
  757.   },
  758.   
  759.   showProgress: function() {
  760.     const pgl = this.progressList; 
  761.     var len = pgl.length;
  762.     var value;
  763.     if(len > 0) {
  764.       value = 0;
  765.       for(var j = len; j-- > 0;) {
  766.         var v = pgl[j].value;
  767.         if(v < 100) {
  768.           value += v;
  769.         } else {
  770.           pgl.splice(j, 1);
  771.           len--;
  772.         }
  773.       }
  774.       value = len > 0 ? Math.round(value / len) : 100;
  775.     } else {
  776.       value = 100;
  777.     }
  778.     this.showProgressValue(value);
  779.   }
  780. ,
  781.   buildGallery: function() {
  782.     var previewURL=null, contentURL=null;
  783.     var win=this.unwrappedWindow;
  784.     if(win._flashgotGB) {
  785.       dump("FGBG: reusing gallery data\n");
  786.       previewURL=win._flashgotGB.previews;
  787.       contentURL=win._flashgotGB.contents;
  788.     } else {
  789.       var links=this.getSelectionLinks(true);
  790.       if(!(links && links.length)) {
  791.         dump("FGBG: no selection links, using "); 
  792.         if(this.popupLink) {
  793.          dump("popup link\n");
  794.          links = [this.popupLink];
  795.         } else {
  796.          dump("all links\n");
  797.          links=this.getLinks(this.checkLink, true);
  798.         }
  799.       }
  800.       var len;
  801.       if(links && (len=links.length)) {
  802.         const previewRX = /\d+.*\.(jpg|jpeg|png|gif|bmp)(\?|$)/i;
  803.         const contentRX = /\d+.*\.[a-z]{2,4}(\?|$)/i;
  804.         const lm = gFlashGotService.lookupMethod; 
  805.         var l, tag, url, imgs, i, iLen, i_item, imgSrc;
  806.         for(var j=0; j<len && ! (contentURL && previewURL); j++) {
  807.           l=links[j];
  808.           tag=l.tagName && l.tagName.toUpperCase();
  809.           url=l.href;
  810.           if(tag!="IMG" && contentRX.test(url)) {
  811.             contentURL=url;
  812.             if(tag=="A" && l.getElementsByTagName ) {
  813.               imgs=l.getElementsByTagName("img");
  814.               i_item=lm(imgs, "item");
  815.               for(i = 0, iLen = lm(imgs,"length")(); i < iLen; i++) {
  816.                 imgSrc = lm(i_item(i),"src")();
  817.                 if(previewRX.test(imgSrc)) {
  818.                   previewURL=imgSrc;
  819.                   break;
  820.                 }
  821.               }
  822.             }
  823.           }
  824.         }
  825.         if( (!previewURL) && (tag=="img" || previewRX.test(url)) ) {
  826.           previewURL=url;
  827.         } 
  828.       }
  829.       if(!previewURL) previewURL="";
  830.       if(previewURL && !contentURL) contentURL=previewURL;
  831.     }
  832.     window.openDialog("chrome://flashgot/content/flashgotGalleryBuilder.xul","_blank",
  833.       "chrome,dialog,centerscreen,resizable",
  834.       { 
  835.         previewURL: previewURL, 
  836.         contentURL: contentURL, 
  837.         referrerURL: this.referrer,
  838.         originalWindow: window,
  839.         tmpDir: gFlashGotService.tmpDir,
  840.         prefs:  gFlashGotService.globals.prefs
  841.       }
  842.     );
  843.   },
  844.   
  845.   rsPremiumHack: function() {
  846.     const bb = getBrowser().browsers; 
  847.     var w, d, f, fj, aa, k, files;
  848.     var allFiles = []; 
  849.     for(var j = 0; j < bb.length; j++) {
  850.       d = (w = bb[j].contentWindow) && w.document;
  851.       if(!d) continue;
  852.       for(fj = d.forms.length; fj-- > 0;) {
  853.         f = d.forms[fj];
  854.         if(/rapidshare\.(?:com|de)/.test(f.action)) { 
  855.           b = f.elements["dl.start"];
  856.           if(b) {
  857.             if(b.length == 2) {
  858.               b = b[0];
  859.             }
  860.             b.type = "hidden";
  861.             f.submit();
  862.             break;
  863.           }
  864.         }
  865.       }
  866.       if(fj == -1 && /\brapid(share|safe)\.[\w]+$/.test(w.location.host)) {
  867.         aa = d.getElementsByTagName("a");
  868.         files = [];
  869.         for(k = 0; k < aa.length; k++) {
  870.           if(/^http:\/\/[^\/]*rapidshare\.(?:com|de)\/files\/\d+.*[^#]$/.test(aa[k].href)) {
  871.             files.push({ href: aa[k].href, description: aa[k].innerHTML });
  872.           }
  873.         }
  874.         if(files.length) {
  875.           allFiles.push(files[Math.round(Math.random() * (files.length - 1))]);
  876.           d.title = "***" + d.title;
  877.         }
  878.       }
  879.     }
  880.     if(allFiles.length) {
  881.       this.download(allFiles);
  882.     }
  883.   }
  884.  
  885. }
  886.  
  887. window.addEventListener("load",  
  888.   function(ev) {
  889.     if(typeof(XPCNativeWrapper)!="function") {
  890.        Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  891.                  .getService(Components.interfaces.mozIJSSubScriptLoader)
  892.                  .loadSubScript("chrome://global/content/XPCNativeWrapper.js", null);
  893.     }
  894.     new FlashGotOverlay();
  895.   }, false);
  896.  
  897.  
  898.  
  899.